The Service Worker
essentially acts as a proxy server between a web application, browser, and the network (when available). This API is designed to create efficient offline experiences by intercepting network requests and taking appropriate actions based on the availability of the network. It can update resources from the server, provide entry points for push notifications, and access background sync APIs.
The Service Worker
is essentially used for caching resources in the browser. However, it goes beyond just caching and further optimizes through the use of workers. It is based on the Web Worker
of HTML5, which means it does not block the execution of the current JavaScript thread. Its main working principles are as follows:
In simple terms, the Service Worker
is a background worker thread that runs continuously, serving as a service. It is well-suited for functionalities that do not require independent resource data or user interaction. The most common use case is intercepting and handling network requests. Here are some key points to note:
Web Worker
, which is an independent thread separate from the JavaScript main thread, allowing resource-intensive operations to be executed without blocking the main thread.Web Worker
.The Service Worker
has other use cases as well, and the standard of Service Worker
can be used to make web platforms more similar to native applications. Some of these use cases include:
Here is an example of a simple Service Worker
application that can still be used when there is no internet connection. The relevant code can be found at https://github.com/WindrunnerMax/webpack-simple-environment/tree/simple--service-worker
. In this example, a simple native Service Worker
is implemented without using any libraries like Workbox
. However, it is worth noting that writing a native Service Worker
can be cumbersome and complex, so using libraries like Workbox
can simplify the process. Before using a Service Worker
, there are some important considerations:
Service Worker
runs on a worker, which means it cannot access the DOM.Service Workers
can only be hosted on HTTPS, although http
can be used for local debugging on localhost
.Service Worker
is not available.First, use Node
to start a basic web
server. You can use the anywhere
package, or any other server of your choice. After executing the command, you can access http://localhost:7890/
. Additionally, it is recommended to restart the server after writing the relevant code. I encountered issues with caching before, including disk cache
and memory cache
, and they were resolved after restarting the server. Also, please note that the link to be opened is localhost
, as the browser may not automatically open to localhost
. If you want to clear the cache, you can click on Clear site data
in the Storage
section of the browser console under the Application
tab. This will clear all the cache on the website. If you are using a server environment such as express
or koa
, you can also try using Service Worker
to cache data requests. Simply provide the path for the data request.
Create an index.html
file and an sw.js
file, and import the relevant resource files. The directory structure is as follows, and you can refer to https://github.com/WindrunnerMax/webpack-simple-environment/tree/simple--service-worker
. Of course, you can directly clone and run a static file server to use it directly.
Simply import the relevant files in the html
file, mainly to leverage the browser environment, and focus on the js
section.
The first step in using Service Worker
is to tell the browser to register a Service Worker
script. In this case, we directly write it in the index.html
file. By default, Service Worker
only works for the root directory /
. If you want to change the scope, you can add a second parameter { scope: "/xxx"}
when registering, or directly specify the path /xxx/sw.js
during registration.
Once the registration is successful, the work of the Service worker
script begins. The following code is written inside the service worker
script. After registration, the install
event will be triggered, and the service worker
script needs to listen for this event. First, the name of the cache
is defined, which serves as the key to identify this cache object. The urlsToCache
array contains the data that will be cached. As long as the relevant path
is provided, even data requests can be cached, not just resource files. However, this can only be done for Get
requests, as determined by the Cache
API. After that, the install
process is carried out. The event.waitUntil
can be understood as the function of new Promise
, which means that it waits for the serviceWorker
to start running before continuing with the subsequent code. The actual parameter it accepts can only be a Promise
. According to the explanation on MDN, it is because some time is needed for oninstall
and onactivate
to complete. The service worker
standard provides a waitUntil
method, which is called when oninstall
or onactivate
is triggered. It accepts a promise
, and until this promise
is successfully resolved, functional events will not be dispatched to the service worker
. After that, the cache
identified by the key
of CACHE_NAME
is retrieved from caches
, and then the path
in the array is added to the cache
using cache.addAll
. When the page is first opened, the Service worker
will automatically request the relevant data and cache it. The data requested using the Service worker
will be displayed with a small gear icon in the Network
tab of the Chrome console, making it easy to recognize.
Next is the activated
phase. If it is the first time loading the sw
, after installation, it will directly enter the activated
phase. However, if the sw
is being updated, the situation becomes more complicated. The process is as follows: First, the old sw
is A
, and the new sw
version is B
. B
enters the install
phase while A
is still in working state, so B
enters the waiting
phase. Only when A
is terminated can B
replace A
and start working normally. There are several ways to trigger the terminated
state: 1) Closing the browser for a period of time. 2) Manually clearing the Service Worker. 3) Skipping the waiting
phase during sw
installation. After that, the activated
phase is entered, and the sw
starts working. In the activated
phase, many meaningful things can be done, such as updating the key
and value
stored in the Cache
. In the code below, any CACHE_NAME
that is not in the whitelist will be cleared. A version control can also be implemented here, where previous versions need to be cleared. Additionally, the current related cache is checked.
Afterwards, it is the stage of intercepting requests. This stage is a crucial stage for the sw
, used to intercept and proxy all specified requests, and perform corresponding operations. All caching operations are done in this stage. First, we intercept all requests. The initial conditional statement is used to prevent all requests from being intercepted and made within the worker. However, it can also be used without the conditional statement. Then, if a request matches a cache, the data is directly retrieved from the cache; otherwise, a new request is made using fetch
. Additionally, if needed, we can cache all requests made without matching during the event response.
Console output when opened for the first time:
Console output when opened for the second time and onwards:
With this, we have completed a simple example. When the page is opened for the second time, we can disconnect the browser's network connection, such as by closing the file server or selecting Offline
in the Network
tab of the console. We can see that the page still loads normally without requiring a network service. Additionally, in the Size
column of the relevant data in the Network
tab, there will be a (ServiceWorker)
indication, indicating that the resources are loaded from the cache data of the ServiceWorker
. You can clone this example from https://github.com/WindrunnerMax/webpack-simple-environment/tree/simple--service-worker
and run it.